-
-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
imageCaptureProcessing maintain EXIF #2902
base: master
Are you sure you want to change the base?
Conversation
Can one of the admins verify this patch? |
Thank you for the submission! Please ensure you meet the eligibility criteria for our program. 📝 Our team will review and process the payment if everything looks good. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @melmathari. Your attempts looks great. Made some clarifying comments, but also wondering if it's possible to add unit tests for the new FileUtil methods you have added to copy the exif data. Thanks!
ExifInterface destExif = new ExifInterface(destFile.getAbsolutePath()); | ||
|
||
// Copy GPS data | ||
String[] tagsToPreserve = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Think we should also include these tags here -
TAG_COPYRIGHT
,
TAG_IMAGE_DESCRIPTION
,
TAG_DATETIME_DIGITIZED
,
TAG_DATETIME_ORIGINAL
,
TAG_EXIF_VERSION
,
TAG_OFFSET_TIME
,TAG_OFFSET_TIME_ORIGINAL
,TAG_OFFSET_TIME_DIGITIZED
,
TAG_GPS_ALTITUDE
,
TAG_GPS_ALTITUDE_REF
,
TAG_GPS_AREA_INFORMATION
ExifInterface.TAG_GPS_LATITUDE_REF, | ||
ExifInterface.TAG_GPS_LONGITUDE, | ||
ExifInterface.TAG_GPS_LONGITUDE_REF, | ||
ExifInterface.TAG_GPS_TIMESTAMP, | ||
ExifInterface.TAG_GPS_DATESTAMP, | ||
// Preserve other important EXIF data | ||
ExifInterface.TAG_DATETIME, | ||
ExifInterface.TAG_ORIENTATION | ||
}; | ||
|
||
for (String tag : tagsToPreserve) { | ||
String value = sourceExif.getAttribute(tag); | ||
if (value != null) { | ||
destExif.setAttribute(tag, value); | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason we are not directly using the method copyExifData
here ?
return scaled; | ||
} | ||
|
||
private static void copyExifData(ExifInterface source, ExifInterface dest) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about directly passing source and destination file paths to this method ?
@damagatchi ok to test |
@shubham1g5 I've addressed the feedback. As for the unit tests, I'm not sure if I'll be able to complete them, i ran into several issues with testImplementation project(path: ':commcare-core', configuration: 'testsAsJar') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@melmathari It's fine to ignore the lint errors in the code you have not changed as the method refactoring will need to be replicated elsewhere in the calling code.
@@ -121,7 +121,7 @@ public static boolean cleanFilePath(String fullPath, String extendedPath) { | |||
|
|||
private static final String illegalChars = "'*','+'~|<> !?:./\\"; | |||
|
|||
public static String SanitizeFileName(String input) { | |||
public static String sanitizeFileName(String input) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
think you can ignore lint errors in the code you have not changed as method renames will need to be replicated while calling the method as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry if I wasn't clear but the file name will need to be reverted here, as otherwise the project fails to compile.
@@ -356,18 +356,17 @@ public static String getGlobalStringUri(String fileLocation) { | |||
return "file://" + fileLocation; | |||
} | |||
|
|||
public static void checkReferenceURI(Resource r, String URI, Vector<MissingMediaException> problems) throws InvalidReferenceException { | |||
Reference mRef = ReferenceManager.instance().DeriveReference(URI); | |||
public static Reference checkReferenceUri(String uri) throws InvalidReferenceException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is causing the build to fail now due to method calls not having the corresponding change, you can ignore lint errors here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this will need to be reverted.
Curious what kind of errors are you facing here and if you have followed the instructions given here to run tests. |
@shubham1g5 Thanks for providing the doc. Unfortunately, I won't be able to commit to the unit testing for this build due to my current schedule. We have tested this on our local implementation though. |
app/lint.xml
Outdated
<ignore path="src/org/commcare/utils/FileUtil.java" /> | ||
<ignore path="src/org/commcare/activities/components/ImageCaptureProcessing.java" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I didn't mean to turn off lint checks for these files, but just to ignore any errors that you have not changed (lint errors doesn't block the merge/approval on PR for us) .
@@ -121,7 +121,7 @@ public static boolean cleanFilePath(String fullPath, String extendedPath) { | |||
|
|||
private static final String illegalChars = "'*','+'~|<> !?:./\\"; | |||
|
|||
public static String SanitizeFileName(String input) { | |||
public static String sanitizeFileName(String input) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry if I wasn't clear but the file name will need to be reverted here, as otherwise the project fails to compile.
@@ -356,18 +356,17 @@ public static String getGlobalStringUri(String fileLocation) { | |||
return "file://" + fileLocation; | |||
} | |||
|
|||
public static void checkReferenceURI(Resource r, String URI, Vector<MissingMediaException> problems) throws InvalidReferenceException { | |||
Reference mRef = ReferenceManager.instance().DeriveReference(URI); | |||
public static Reference checkReferenceUri(String uri) throws InvalidReferenceException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this will need to be reverted.
@shubham1g5 Why did the developer bring a lint roller to the code review? Because we used SuppressLint to silence those pesky errors — nothing escapes our lint-taming prowess! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@melmathari Indeed lol. Although what I have been trying to say is don't worry about the lint check and let it fail. No roller needed 🤣
app/src/org/commcare/activities/components/ImageCaptureProcessing.java
Outdated
Show resolved
Hide resolved
63bee37
to
e9f1985
Compare
Change requests change request SuppressLint SuppressLint imageCaptureProcessing.java
@melmathari We are seeing instrumentation test failures on this PR which looks related to media handling. You should be able to run these tests locally to look into the failures. |
@shubham1g5 Thanks, I will take some time to test this a bit more locally |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious if the error with tests was due to us trying to copy the exif data from non image files ?
The file isn't an image (mimeType check) The image doesn't have EXIF data (ExifInterface handles this gracefully) There are any issues reading/writing EXIF data (caught and logged) The only failure that would propagate up is if the initial file copy fails, which is appropriate since that's the core operation we need to succeed.
Correct, this was the case. |
Images taken in CommCare were losing their EXIF metadata, including critical GPS/location data, during processing. This created headaches for users who needed that juicy metadata intact, especially for location-based verification.
Resolves issue #2689 and #2743
The Fix
We pimped the image capture and processing workflow to make EXIF data stick, no matter what. Here's what we did:
Injected EXIF-aware copying for raw image files.
Ensured EXIF data is kept intact during image scaling.
Made sure key EXIF tags stay in the game:
How We Pulled It Off
copyFileWithExifData()
to keep EXIF data alive during file copying.scaleAndSaveImageWithExif()
for maintaining EXIF while scaling images.ImageCaptureProcessing
to use our new EXIF-hugging methods.ExifInterface
API for bulletproof metadata handling.Test Drive
Basic EXIF Check
Scaled Image Test
Encrypted Image Test
Edge Cases
Tools to Verify
exiftool
to peek at the EXIF data.Additional Notes
/claim #2689